
#include "Parameter.h"
#include "ParameterSet.h"

using namespace System;
using namespace ttg_internal::utils;

//-----------------
//--- Parameter ---
//-----------------

Parameter::Parameter(String ^name,
					 ParameterInfo ^info,
					 ParameterSet ^owner,
					 System::String ^depPropertyName)
{
	_owner = owner;
	_info = info;
	value = "";
	buffer = "";
	this->name = name;
	_depPropertyName = depPropertyName;
	should_apply = false;
	was_modified = true;
	is_locked = false;
	is_read_only = false;
	locker = new ttg::threads::FastCriticalSection();
}

System::String ^Parameter::ValueGet(bool should_skip)
{
	String ^res;
	locker->enter();
	res = value;
	if (should_skip)
		was_modified = false;
	locker->leave();
	return res;
}

void Parameter::ValueSet(System::String ^value)
{
	locker->enter();
	//Checking.
	if (!_info->CanBeAssigned(value))
	{
		was_modified = true;			//to rewrite new cached value.
		locker->leave();
		return;
	}
	//Setting.
	bool should_notify;
	if (is_locked)
	{
		buffer = value;
		should_apply = true;
	}
	else
	{
		this->value = value;
		was_modified = true;
		should_notify = true;
	}
	locker->leave();
	if (should_notify)
	{
		onPropertyChange("Value");
		if (_depPropertyName != nullptr)
			onPropertyChange(_depPropertyName);
	}
}

void Parameter::lock()
{
	locker->enter();
	is_locked = true;
	locker->leave();
}

void Parameter::unLock()
{
	bool should_notify = false;
	locker->enter();
	if (is_locked && should_apply)
	{
		value = buffer;
		should_apply = false;
		was_modified = true;
		should_notify = true;
	}
	is_locked = false;
	locker->leave();
	if (should_notify)
	{
		onPropertyChange("Value");
		if (_depPropertyName != nullptr)
			onPropertyChange(_depPropertyName);
	}
}

bool Parameter::wasModified()
{
	bool res;
	locker->enter();
	res = was_modified;
	locker->leave();
	return res;
}
